
package com.zcsy.seller.web.common.aop;

import java.lang.reflect.Method;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.mongodb.util.JSON;
import com.zcsy.commons.model.RequestConstants;
import com.zcsy.commons.model.RequestContext;
import com.zcsy.commons.util.BrowserUtils;
import com.zcsy.commons.util.DateUtils;
import com.zcsy.commons.util.IpUtil;
import com.zcsy.manage.model.system.Log;
import com.zcsy.manage.model.system.User;
import com.zcsy.manage.persistence.system.LogDao;
import com.zcsy.seller.web.common.annotation.SystemControllerLog;
import com.zcsy.seller.web.common.annotation.SystemServiceLog;


/**
 * @Title: LogAspect.java
 * @Package： com.zcsy.shop.web.aop 
 * @Description: 日志AOP管理
 *  〈功能详细描述〉
 *
 * @author caiyinli 13277030520@163.com
 * @Copyright: 2015 武汉中财数元信息技术有限公司 All rights reserved.
 * @date 2015年8月25日
 * @version 1.0
 * @see JDK1.7.0_75
 * @since
 */

@Component
@Aspect
public class LogAspect {
	
	private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

	@Autowired
	private LogDao logDao;
	
	 /**
		 * @Title: serviceAspect
		 * @Description: 服务层方法切入点
		 * @throws
		 */ 
		 @Pointcut("@annotation(com.framework.annotation.SystemServiceLog)") 
		 public  void serviceAspect() {  
		     
		 }  
		
		 //Controller层切点  
	     @Pointcut("@annotation(com.framework.annotation.SystemControllerLog)")  
	     public  void controllerAspect() { 
	    	 
	     }  
	     
	     @Before("controllerAspect()") 
	     public  void doBefore(JoinPoint joinPoint) {  
	    	 HttpServletRequest request = RequestContext.getRequest();  
	         HttpSession session = request.getSession();  
	         //读取session中的用户  
	         User user = (User) session.getAttribute(RequestConstants.USER_SESSION_ID);  
	         if(user!=null){
	        	//请求的IP  
	             String ip = IpUtil.getIp(request);   
	              try {  
	                 logger.info("Name:"+user.getUsername()+"--IP:" + ip+" --Method:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  
	                 Log Log = new Log();
	                 Log.setLogcontent(getControllerMethodDescription(joinPoint));
	                 Log.setOperatetime(DateUtils.getFmtDate());
	                 Log.setUserId(String.valueOf(RequestContext.getUserId()));
	                 Log.setBrowser(BrowserUtils.checkBrowse(request));
	                 Log.setIp(ip);
	                 logDao.insert(Log);
	             }  catch (Exception e) {  
	                 logger.error("异常信息:{}", e);  
	             }  
	         }
	         
	     }
	     
	     /** 
	      * 异常通知 用于拦截service层记录异常日志 
	      * 
	      * @param joinPoint 
	      * @param e 
	      */  
	     @AfterThrowing(pointcut = "serviceAspect()", throwing = "e")  
	      public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) {  
	    	 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();  
	         HttpSession session = request.getSession();  
	         //读取session中的用户  
	         User user = (User) session.getAttribute(RequestConstants.USER_SESSION_ID);  
	         //获取请求ip  
	         String ip = IpUtil.getIp(request);  
	         //获取用户请求方法的参数并序列化为JSON格式字符串  
	         String params = "";  
	          if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {  
	              for ( int i = 0; i < joinPoint.getArgs().length; i++) {  
	                 params += JSON.serialize(joinPoint.getArgs()[i]) + ";";  
	             }  
	         }  
	          try {  
	               /*========控制台输出=========*/  
	             System.out.println("=====异常通知开始=====");  
	             System.out.println("异常代码:" + e.getClass().getName());  
	             System.out.println("异常信息:" + e.getMessage());  
	             System.out.println("异常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  
	             System.out.println("方法描述:" + getServiceMthodDescription(joinPoint));  
	             System.out.println("请求人:" + user.getUsername());  
	             System.out.println("请求IP:" + ip);  
	             System.out.println("请求参数:" + params);  
	              
	             System.out.println("=====异常通知结束=====");  
	         }  catch (Exception ex) {  
	             //记录本地异常日志  
	             logger.error("==异常通知异常==");  
	             logger.error("异常信息:{}", ex.getMessage());  
	         }  
	     }  

	     /** 
	      * 获取注解中对方法的描述信息 用于Controller层注解 
	      * 
	      * @param joinPoint 切点 
	      * @return 方法描述 
	      * @throws Exception 
	      */  
	      public static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {  
	         String targetName = joinPoint.getTarget().getClass().getName();  
	         String methodName = joinPoint.getSignature().getName();  
	         Object[] arguments = joinPoint.getArgs();  
	         Class targetClass = Class.forName(targetName);  
	         Method[] methods = targetClass.getMethods();  
	         String description = "";  
	          for (Method method : methods) {  
	              if (method.getName().equals(methodName)) {  
	                 Class[] clazzs = method.getParameterTypes();  
	                  if (clazzs.length == arguments.length) {  
	                     description = method.getAnnotation(SystemControllerLog. class).description();  
	                      break;  
	                 }  
	             }  
	         }  
	          return description;  
	     }  
	      
	      /** 
	       * 获取注解中对方法的描述信息 用于service层注解 
	       * 
	       * @param joinPoint 切点 
	       * @return 方法描述 
	       * @throws Exception 
	       */  
	       public  static String getServiceMthodDescription(JoinPoint joinPoint)  
	               throws Exception {  
	          String targetName = joinPoint.getTarget().getClass().getName();  
	          String methodName = joinPoint.getSignature().getName();  
	          Object[] arguments = joinPoint.getArgs();  
	          Class targetClass = Class.forName(targetName);  
	          Method[] methods = targetClass.getMethods();  
	          String description = "";  
	           for (Method method : methods) {  
	               if (method.getName().equals(methodName)) {  
	                  Class[] clazzs = method.getParameterTypes();  
	                   if (clazzs.length == arguments.length) {  
	                       description = method.getAnnotation(SystemServiceLog. class).description();  
	                       break;  
	                  }  
	              }  
	          }  
	           return description;  
	      }  
	
}
